package com.oromwin.repos.common;

import java.io.File;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.UUID;

import org.apache.commons.logging.Log;

import com.oromwin.repos.socket.request.Request;
import com.oromwin.repos.socket.request.file.CreateFileRequest;
import com.oromwin.repos.socket.request.volume.CreateVolumeRequest;

public class Common {
    private static Log log = Logger.getLog(Common.class);
    public final static int SIZE_OF_BYTE = 1;
    public final static int SIZE_OF_INT = 4;
    public final static int SIZE_OF_LONG = 8;
    
    public static final String requestPrefix = "com.oromwin.repos.socket.request.";
    public static final String responsePrefix = "com.oromwin.repos.socket.response.";
    
    public enum LockType { READ, WRITE }
    
    public enum ReposType { FILE, MEDIA, VOLUME }
    
    public enum Status { CREATE, UPDATE, DELETE }
    
    public enum ErrorCode {
        DEBUG, INFO, WARN, ERROR, FATAL
    }
    
    public final static int SIZE_OF_REPOS_HEADER = (
            SIZE_OF_BYTE + // sizeof ReposType
            SIZE_OF_BYTE // sizeof ReposAction
    );
    
    public final static class Message {
        public final static String NOT_IMPLEMENTED_METHOD_INVOKE = "Not implemented method invoked.";
    }
    
    public final static class Category {
        public final static String NORMAL = "normal";
    }
    
    public static enum ReposResult {
        Success, Failure
    };

    public final static class CharSet { // http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html
        public final static String USASCII = "US-ASCII"; // Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set
        public final static String ISO8859 = "ISO-8859-1"; // ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
        public final static String UTF8 = "UTF-8"; // Eight-bit UCS Transformation Format
        public final static String UTF16BE = "UTF-16BE"; // Sixteen-bit UCS Transformation Format, big-endian byte order
        public final static String UTF16LE = "UTF-16LE"; // Sixteen-bit UCS Transformation Format, little-endian byte order
        public final static String UTF16 = "UTF-16"; // Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark
    }

    public final static class Separator {
        public final static String PERIOD = ".";
        public final static String SLASH = "/"; // use this instead of File.separator
        public final static String COMMA = ",";
        public final static String BACKSLASH = "\\";
    }
    
    public final static class FileExt {
        public final static String TEMPFILE = "TMP";
        public final static String BINFILE = "BIN";
    }
    
    public final static String DEFAULT_PROPERTIES = "resources/default.properties";
    
    public static String getFileFormat(String filePath) {
        String format = null;
        int beginIndex = filePath.lastIndexOf(".");
        if (beginIndex < 0 || beginIndex > filePath.length()) {
            format = Common.FileExt.BINFILE;
        } else {
            format = filePath.substring(beginIndex).toUpperCase();
        }
        return format;
    }

    public static String datetime() {
        // example_ "yyyy-MM-dd'T'HH:mm:ss,SSS'Z'"
        return datetime("yyyyMMddHHmmss");
    }
    
    public static String datetime(String format) {
        SimpleDateFormat ISO8601UTC = new SimpleDateFormat(format);
//        ISO8601UTC.setTimeZone(TimeZone.getTimeZone("UTC"));
        String now = ISO8601UTC.format(new Date());
        return now;
    }

    public static class UniqueId {
        public static String generate() {
            return UUID.randomUUID().toString();
        }
    }
    
    public static LockType getLockTypeOfPacket(Request req) {
        if (req instanceof CreateFileRequest) {
            return LockType.WRITE;
        } else if (req instanceof CreateVolumeRequest) {
            return LockType.WRITE;
        } else {
            return LockType.READ;
        }
    }
    
    public static class FilePath {
        public static File generate(File rootPath, String fileId) throws ReposException {
            String midPath = null;
            File path = null;
            try {
                midPath = fileId.substring(0,1) + File.separator + fileId.substring(1, 2);
                path = new File(rootPath, midPath);
                path.mkdirs();
            } catch (NullPointerException e) {
                String message = String.format("Input path is null, command {mkdir %s}", path);
                throw ReposException.create(log, message); 
            } catch (SecurityException e) {
                String message = String.format("Can't access input path, command {mkdir %s}", path);
                throw ReposException.create(log, message); 
            }
            return path; 
        } 
    }
    
    public final static String ConvertSimpleTimeFormat(long time) {
        SimpleDateFormat sdfCurrent = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Timestamp currentTime = new Timestamp(time);
        return sdfCurrent.format(currentTime);
    }
    
    public final static class OS {
        public static boolean isWindows = false;
        public static String SEPARATOR = null;
        static {
            String os = System.getProperty("os.name", "");
            if (os.startsWith("Windows")) {
                isWindows = true;
                SEPARATOR = "\\\\";
            } else {
                isWindows = false;
                SEPARATOR = "/";
            }
        }
    }
}
